const WebSocket = require('ws');
const fs = require('fs');
const path = require('path');

// 配置日志
const logger = {
  info: (message) => console.log(`[INFO] ${new Date().toISOString()} - ${message}`),
  warning: (message) => console.warn(`[WARNING] ${new Date().toISOString()} - ${message}`),
  error: (message) => console.error(`[ERROR] ${new Date().toISOString()} - ${message}`),
  debug: (message) => console.debug(`[DEBUG] ${new Date().toISOString()} - ${message}`)
};

// 常量定义
const ORBIT_TYPES = {
  LEO: 'leo',  // 低轨道
  MEO: 'meo',  // 中轨道
  GEO: 'geo',   // 地球同步轨道
  SGO: 'sgo'    // 静轨威慑层
};

const SATELLITE_STATUS = {
  ONLINE: 'online',
  OFFLINE: 'offline',
  ALERT: 'alert'
};

// 卫星数据生成器
class SatelliteDataGenerator {
  constructor() {
    this.satellite_count = 300;  // 总卫星数量
    this.leo_count = 200;       // 低轨卫星数量
    this.meo_count = 80;        // 中轨卫星数量
    this.geo_count = 6;        // 地球同步轨道卫星数量
    this.sgo_count = 14;        // 静轨威慑层卫星数量   
    // 配置文件路径
    this.config_file = path.join(__dirname, 'satellite_status_config.json');
    this.config = this.loadConfig();
    // 生成初始卫星数据
    this.satellites = this._generateInitialData();
    logger.info(`已生成 ${this.satellites.length} 颗卫星初始数据`);
    this.last_update = Date.now();
    // 当前场景
    this.current_scenario = null;
    this.scenario_start_time = null;
    this.scenario_duration = 0;
  }
  
  loadConfig() {
    try {
      if (fs.existsSync(this.config_file)) {
        const config = JSON.parse(fs.readFileSync(this.config_file, 'utf-8'));
        logger.info(`成功加载卫星状态配置文件: ${this.config_file}`);
        return config;
      } else {
        logger.warning(`卫星状态配置文件不存在: ${this.config_file}，将使用默认配置`);
        return {};
      }
    } catch (e) {
      logger.error(`加载卫星状态配置文件失败: ${e}`);
      return {};
    }
  }
  
  _generateInitialData() {
    const satellites = [];
    
    // 生成低轨卫星
    for (let i = 1; i <= this.leo_count; i++) {
      const satellite = this._generateSatellite(i, ORBIT_TYPES.LEO);
      satellites.push(satellite);
    }
    
    // 生成中轨卫星
    for (let i = this.leo_count + 1; i <= this.leo_count + this.meo_count; i++) {
      const satellite = this._generateSatellite(i, ORBIT_TYPES.MEO);
      satellites.push(satellite);
    }
    
    // 生成地球同步轨道卫星
    for (let i = this.leo_count + this.meo_count + 1; i <= this.leo_count + this.meo_count + this.geo_count; i++) {
      const satellite = this._generateSatellite(i, ORBIT_TYPES.GEO);
      satellites.push(satellite);
    }
    
    // 生成静轨威慑层卫星
    for (let i = this.leo_count + this.meo_count + this.geo_count + 1; i <= this.satellite_count; i++) {
      const satellite = this._generateSatellite(i, ORBIT_TYPES.SGO);
      satellites.push(satellite);
    }
    
    return satellites;
  }
  
  _generateSatellite(satellite_id, orbit_type) {
    let altitude, inclination, longitude, latitude;
    
    // 根据轨道类型设置不同的参数
    if (orbit_type === ORBIT_TYPES.LEO) {
      // 低轨道卫星 (160-2000km)
      altitude = this._randomFloat(0.025, 0.3);  // 归一化高度
      inclination = this._randomChoice([45, 55, 65, 75, 85, 95]);  // 轨道倾角
      
      // 按轨道面分组
      const orbit_plane = satellite_id % 3 + 1;  // 分为3个轨道面
      
      // 根据轨道面设置初始位置
      const longitude_offset = (orbit_plane - 1) * 120;  // 三个轨道面在经度上均匀分布
      const position_in_plane = (satellite_id - 1) % Math.floor(this.leo_count / 3);  // 每个轨道面内的位置
      const spacing = 360 / Math.floor(this.leo_count / 3);  // 同一轨道面内卫星的间距
      
      longitude = (longitude_offset + position_in_plane * spacing) % 360;
      if (longitude > 180) {
        longitude -= 360;
      }
      
      latitude = this._randomFloat(-inclination, inclination);
      
    } else if (orbit_type === ORBIT_TYPES.MEO) {
      // 中轨道卫星 (2000-35786km)
      altitude = this._randomFloat(0.3, 0.6);  // 归一化高度
      inclination = this._randomChoice([45, 55, 65]);  // 轨道倾角
      
      // 按轨道面分组
      const orbit_plane = satellite_id % 2 + 1;  // 分为2个轨道面
      
      // 根据轨道面设置初始位置
      const longitude_offset = (orbit_plane - 1) * 180;  // 两个轨道面在经度上均匀分布
      const position_in_plane = (satellite_id - this.leo_count - 1) % Math.floor(this.meo_count / 2);  // 每个轨道面内的位置
      const spacing = 360 / Math.floor(this.meo_count / 2);  // 同一轨道面内卫星的间距
      
      longitude = (longitude_offset + position_in_plane * spacing) % 360;
      if (longitude > 180) {
        longitude -= 360;
      }
      
      latitude = this._randomFloat(-inclination, inclination);
      
    } else if (orbit_type === ORBIT_TYPES.GEO) {
      // 地球同步轨道卫星 (35786km)
      altitude = 0.6;  // 归一化高度
      inclination = 0;
      // 每15°经度部署卫星组
      const satellite_group = Math.floor((satellite_id - 1) / 3) + 1;  // 每组3颗
      const position_in_group = (satellite_id - 1) % 3;  // 组内位置
      
      // 基本经度范围
      const base_longitude = -180 + (satellite_group - 1) * 40;  // 大约每40°部署一组
      longitude = base_longitude + (position_in_group - 1) * 5;  // 组内间隔5°
      
      // 地球同步轨道卫星纬度接近赤道
      latitude = this._randomFloat(-1, 1);  // 赤道附近小范围随机
    
    } else {  // SGO
      // 静轨威慑层卫星 (35786km)
      altitude = 0.65;  // 归一化高度，稍高于GEO
      inclination = 0;  // 轨道倾角为0
      
      // 按轨道面分组：西太组和印度洋组
      const is_west_pacific = (satellite_id % 2 === 0);  // 偶数ID为西太组，奇数ID为印度洋组
      
      if (is_west_pacific) {
        // 西太组 (115°E-125°E)
        const base_longitude = 120;  // 西太组中心经度
        longitude = this._randomFloat(115, 125);  // 在西太组经度范围内随机分布
      } else {
        // 印度洋组 (65°E-75°E)
        const base_longitude = 70;  // 印度洋组中心经度
        longitude = this._randomFloat(65, 75);  // 在印度洋组经度范围内随机分布
      }
      
      // 静轨威慑层卫星纬度接近赤道，但允许小范围振动(±2°)
      latitude = this._randomFloat(-2, 2);
    }
    
    // 生成随机状态
    const status_random = Math.random();
    let status;
    if (status_random > 0.92) {
      status = SATELLITE_STATUS.ALERT;
    } else if (status_random > 0.75) {
      status = SATELLITE_STATUS.OFFLINE;
    } else {
      status = SATELLITE_STATUS.ONLINE;
    }
    
    // 构建卫星对象
    const satellite = {
      id: `SAT-${String(satellite_id).padStart(3, '0')}`,
      name: `Satellite-${satellite_id}`,
      orbitType: orbit_type,
      status: status,
      position: {
        latitude: latitude,
        longitude: longitude,
        altitude: altitude
      },
      inclination: inclination,  // 轨道倾角
      velocity: this._calculateVelocity(orbit_type),  // 速度
      launchDate: this._generateLaunchDate(),  // 发射日期
      subsystems: {
        power: 90 + Math.random() * 10,
        comm: status !== SATELLITE_STATUS.OFFLINE,
        propulsion: 80 + Math.random() * 20,
        thermal: 85 + Math.random() * 15
      },
      last_update: Date.now()
    };
    
    // 如果状态不是在线，调整电源子系统数值
    if (status !== SATELLITE_STATUS.ONLINE) {
      satellite.subsystems.power = Math.random() * 70;
    }
    
    return satellite;
  }
  
  _calculateVelocity(orbit_type) {
    // 根据轨道类型计算卫星速度
    if (orbit_type === ORBIT_TYPES.LEO) {
      return this._randomFloat(7.0, 8.0);  // km/s
    } else if (orbit_type === ORBIT_TYPES.MEO) {
      return this._randomFloat(4.0, 5.0);  // km/s
    } else if (orbit_type === ORBIT_TYPES.GEO) {
      return 3.07;  // km/s
    } else {  // SGO
      return this._randomFloat(6.0, 7.0);  // km/s
    }
  }
  
  _generateLaunchDate() {
    // 生成随机发射日期
    const year = this._randomInt(2015, 2023);
    const month = this._randomInt(1, 12);
    const day = this._randomInt(1, 28);  // 简化处理，避免月份天数问题
    return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
  }
  
  _randomFloat(min, max) {
    return min + Math.random() * (max - min);
  }
  
  _randomInt(min, max) {
    return Math.floor(min + Math.random() * (max - min + 1));
  }
  
  _randomChoice(array) {
    return array[Math.floor(Math.random() * array.length)];
  }
  
  getSatellites() {
    // 获取所有卫星数据
    return {
      type: 'satellites',
      data: this.satellites,
      last_update: Date.now()
    };
  }
  
  updateSatellites() {
    // 更新卫星状态和位置
    try {
      if (fs.existsSync(this.config_file)) {
        const config = JSON.parse(fs.readFileSync(this.config_file, 'utf-8'));
        
        // 检查配置文件是否包含卫星状态信息
        if (config.satellites && typeof config.satellites === 'object') {
          // 遍历所有卫星
          for (let i = 0; i < this.satellites.length; i++) {
            const satellite = this.satellites[i];
            const sat_id = satellite.id;
            const orbit_type = satellite.orbitType;
            
            // 获取轨道类型对应的键
            let orbit_key = null;
            if (orbit_type === 'leo') {
              orbit_key = 'LEO';
            } else if (orbit_type === 'meo') {
              orbit_key = 'MEO';
            } else if (orbit_type === 'geo') {
              orbit_key = 'GEO';
            } else if (orbit_type === 'sgo') {
              orbit_key = 'SGO';
            }
            
            // 如果轨道类型对应的键存在于配置文件中
            if (orbit_key && config.satellites[orbit_key]) {
              // 遍历该轨道类型下的卫星配置
              for (const sat_config of config.satellites[orbit_key]) {
                if (sat_config.id === sat_id) {
                  const new_status = sat_config.status;
                  // 更新卫星状态
                  satellite.status = new_status;
                  break;
                }
              }
            }
          }
        }
      }
      
      // 更新卫星位置
      this._updateSatellitePositions();
      
      return this.satellites;
    } catch (e) {
      logger.error(`更新卫星数据时出错: ${e}`);
      console.error(e);
      return this.satellites;
    }
  }
  
  _updateSatellitePositions() {
    // 更新卫星位置
    for (let i = 0; i < this.satellites.length; i++) {
      const satellite = this.satellites[i];
      
      // 更新经度
      const orbit_type = satellite.orbitType;
      let longitude_change = (Math.random() - 0.5) * 2;
      
      // 不同轨道类型的移动速度不同
      if (orbit_type === ORBIT_TYPES.GEO) {
        // 静止轨道移动很慢
        longitude_change *= 0.01;
      } else if (orbit_type === ORBIT_TYPES.MEO) {
        // 中轨卫星速度适中
        longitude_change *= 3;
      } else if (orbit_type === ORBIT_TYPES.SGO) {
        // 静轨威慑层卫星速度较快
        longitude_change *= 4;
      } else {  // LEO
        // 低轨卫星速度快
        longitude_change *= 5;
      }
      
      // 更新经度
      satellite.position.longitude = (satellite.position.longitude + longitude_change) % 360;
      if (satellite.position.longitude > 180) {
        satellite.position.longitude -= 360;
      }
      
      // 更新纬度（小幅波动）
      if (orbit_type !== ORBIT_TYPES.GEO) { // 非静止轨道纬度会变化
        const latitude_change = (Math.random() - 0.5) * (orbit_type === ORBIT_TYPES.LEO ? 1 : 0.5);
        const new_latitude = satellite.position.latitude + latitude_change;
        // 限制在合理范围内
        const max_latitude = satellite.inclination;
        satellite.position.latitude = Math.max(-max_latitude, Math.min(max_latitude, new_latitude));
      }
      
      // 更新时间戳
      satellite.last_update = Date.now();
    }
    
    // 更新全局时间戳
    this.last_update = Date.now();
  }
}

// 创建WebSocket服务器
class SatelliteServer {
  constructor(port) {
    this.port = port;
    this.clients = new Set();
    this.dataGenerator = new SatelliteDataGenerator();
    this.running = true;
    this.server = null;
    this.updateInterval = null;
  }
  
  start() {
    // 创建WebSocket服务器
    this.server = new WebSocket.Server({ port: this.port });
    
    // 监听连接事件
    this.server.on('connection', (ws, req) => {
      const ip = req.socket.remoteAddress;
      logger.info(`新客户端连接: ${ip}`);
      
      // 添加客户端
      this.clients.add(ws);
      
      // 发送初始卫星数据
      const initialData = this.dataGenerator.getSatellites();
      ws.send(JSON.stringify(initialData));
      
      // 如果广播循环尚未启动，则启动它
      if (!this.updateInterval) {
        this.startBroadcastLoop();
      }
      
      // 监听消息事件
      ws.on('message', (message) => {
        logger.debug(`收到客户端消息: ${message}`);
      });
      
      // 监听关闭事件
      ws.on('close', () => {
        logger.info(`客户端断开连接: ${ip}`);
        
        // 从集合中移除客户端
        this.clients.delete(ws);
        
        // 如果没有客户端连接，停止广播循环
        if (this.clients.size === 0) {
          this.stopBroadcastLoop();
          logger.info("所有客户端已断开，停止数据广播");
        }
      });
      
      // 监听错误事件
      ws.on('error', (error) => {
        logger.error(`WebSocket错误: ${error}`);
      });
    });
    
    logger.info(`卫星状态服务器已启动，监听端口: ${this.port}`);
  }
  
  startBroadcastLoop() {
    // 启动广播循环
    this.updateInterval = setInterval(() => {
      if (this.clients.size > 0) {
        try {
          // 更新卫星数据
          const satellites = this.dataGenerator.updateSatellites();
          
          // 获取当前时间戳
          const currentTimestamp = Date.now();
          
          // 构建包含类型和时间戳的消息格式
          const message = {
            type: "satellites",
            data: satellites,
            timestamp: currentTimestamp,
            forceUpdate: true  // 添加强制更新标志
          };
          
          // 序列化数据
          const serializedData = JSON.stringify(message);
          
          // 广播给所有客户端
          this.clients.forEach((client) => {
            try {
              if (client.readyState === WebSocket.OPEN) {
                client.send(serializedData);
              }
            } catch (e) {
              logger.error(`向客户端发送数据时出错: ${e}`);
              this.clients.delete(client);
            }
          });
        } catch (e) {
          logger.error(`更新或广播数据时出错: ${e}`);
        }
      }
    }, 1000);  // 每1秒更新一次
    
    logger.info("已启动数据广播循环");
  }
  
  stopBroadcastLoop() {
    // 停止广播循环
    if (this.updateInterval) {
      clearInterval(this.updateInterval);
      this.updateInterval = null;
    }
  }
  
  stop() {
    // 停止服务器
    this.running = false;
    this.stopBroadcastLoop();
    
    if (this.server) {
      this.server.close(() => {
        logger.info("WebSocket服务器已关闭");
      });
    }
  }
}

// 创建并启动服务器
const server = new SatelliteServer(8081);
server.start();

// 处理进程终止信号
process.on('SIGINT', () => {
  logger.info("收到终止信号，服务器正在关闭...");
  server.stop();
  process.exit(0);
});

process.on('SIGTERM', () => {
  logger.info("收到终止信号，服务器正在关闭...");
  server.stop();
  process.exit(0);
}); 